#if !defined(_APP_DEVICE)
#define _APP_DEVICE
#include "app_message.h"
#include "app_buffer.h"
#include "pthread.h"


typedef enum
{
    DEVICE_TYPE_NONE ,
    DEVICE_TYPE_SERIAL,
    DEVICE_TYPE_CAN
}DeviceType;

typedef struct Device Device;

// 设备结构体
struct Device
{
    char *file_name; // 文件名称 带完整路径
    int fd; // 文件描述符
    DeviceType dev_type;// 设备类型 (串口 ，CAN )
    ConnectionType conn_type; // 连接类型 (蓝牙， lora  ,wifi)
    Buffer *read_buf; // 读缓冲区
    Buffer *write_buf; // 写缓冲区
    int (*post_read)(Device *device ,char *data , int len); // 读后处理函数指针（数据转换硬件数据变为 字节数组）
    int (*pre_write)(Device *device ,char *data , int len); // 写前处理函数指针（字节数组变为 硬件数据）
    pthread_t read_thread;// 读取硬件的线程 
    int running;// 运行状态  0 关闭  1 运行中 
    long long last_write_ts;// 上次写入时间 （用于 保证写入间隔）
    long write_interval_ms; //距离上一次写入时间的间隔
} ;

/**
 * 设备的初始化
 * 1  打开文件 产生文件描述符 
 * 2  初始化设备结构体的各个属性
 */
Device *app_device_init(char *file_name);

/**
 * 释放设备资源
 */
void app_device_free(Device *device);

/**
 * 启动设备  进程的主线程 启动设备线程
 * @  1. 启动读取硬件设备的线程 调用app_device_read_dev_file
 * @return 0 成功 -1 失败
 */
int app_device_start(Device *device);


/**
 * 读取硬件设备文件的数据 (异步)   设备的读取线程
 * @param 实际上是Device 结构体指针 
 *  1 持续读取设备文件内容
 *  2 写入读缓冲区
 *  3  向线程池提交任务 （发送数据的任务）调用app_device_send_mqtt
 */
 void *app_device_read_dev_file(void *arg);

 /**
  *  向消息队列中写入数据    线程池中的线程
  * @param 实际上是Device 结构体指针 
  */
void * app_device_send_mqtt(void *arg);


/**
 * 从路由器接收数据 
 *  1 写入数据到写缓冲区 
 *  2 提交任务给a线程池（任务： 将数据写入设备文件）
 */
int app_device_recv_router(Device *device ,char *data , int len); 



/**
 * 把设备写缓冲区的数据写入设备文件
 * @param 实际上是Device 结构体指针
 * 1 读取写缓冲区的数据
 * 2 将数据写入设备文件
 */
void *app_device_write_dev_file(void *arg);



#endif // _APP_DEVICE
